package com.zhiwang.planet.ui.my

import android.annotation.SuppressLint
import android.graphics.Color
import android.graphics.drawable.ColorDrawable
import android.os.Bundle
import android.text.TextUtils
import android.view.Menu
import android.view.MenuItem
import android.view.View
import androidx.appcompat.app.AlertDialog
import androidx.databinding.DataBindingUtil
import androidx.lifecycle.Observer
import com.cmcm.cmgame.CmGameSdk
import com.cmcm.cmgame.IGameAccountCallback
import com.cmcm.cmgame.IGamePlayTimeCallback
import com.zhiwang.planet.R
import com.zhiwang.planet.databinding.ActivityMyGameListBinding
import com.zhiwang.planet.di.component.DaggerUserComponent
import com.zhiwang.planet.di.module.AccountModule
import com.zhiwang.planet.di.module.AutoDisposeModule
import com.zhiwang.planet.mvp.p.UserPresenter
import com.zhiwang.planet.mvvm.model.RestApi
import com.zhiwang.planet.mvvm.model.entity.main.TinyGameAccountInfo
import com.zhiwang.planet.mvvm.model.request.GamePlayTimeReport
import com.zhiwang.planet.mvvm.viewmodel.ItemDecorationViewModel
import com.zhiwang.planet.mvvm.viewmodel.entertain.MyPlayedGameViewModel
import com.zhiwang.planet.mvvm.viewmodel.entertain.PlayGameConnection
import com.zhiwang.planet.mvvm.viewmodel.entertain.mapMyPlayedGme
import com.zhiwang.planet.ui.BaseActivity
import com.zhiwang.planet.util.*
import kotlinx.android.synthetic.main.activity_my_game_list.*
import kotlinx.android.synthetic.main.play_time_dialog.view.*
import kotlinx.coroutines.*
import javax.inject.Inject

@SuppressLint("Registered")
class MyGameListActivity : BaseActivity(), CoroutineScope by MainScope(), IGameAccountCallback, IGamePlayTimeCallback {


    override fun initInjection() {
        super.initInjection()
        DaggerUserComponent.builder()
                .accountModule(AccountModule(this))
                .appComponent(getAppComponent())
                .autoDisposeModule(AutoDisposeModule(this))
                .build()
                .inject(this)
    }


    @Inject
    lateinit var myGameViewModel: MyPlayedGameViewModel


    @Inject
    lateinit var decorationViewModel:ItemDecorationViewModel

    @Inject
    lateinit var userPresenter: UserPresenter

    private var gameStartTime = System.currentTimeMillis()

    private var playing = false

    @Inject
    lateinit var restApi: RestApi

    var gameId: String = ""

    private var currToken: String = ""

    private val removeIds = arrayListOf<String>()

    private var active = false

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        val binding = DataBindingUtil.setContentView<ActivityMyGameListBinding>(this, R.layout.activity_my_game_list)

        setSupportActionBar(toolbar)
        binding.lifecycleOwner = this
        myGameViewModel.errHandler = this::onError
        binding.vm = myGameViewModel
        binding.playVm = PlayGameConnection
        binding.decorVm = decorationViewModel

        Utils.setStatusBar(this, false, false)
        myGameViewModel.start()

        PlayGameConnection.playGame.observe(this, Observer {
            playMiniGame(it)
        })

        PlayGameConnection.checkedGame.observe(this, Observer {
            addRemoveGame(it)
        })

        PlayGameConnection.uncheckedGame.observe(this, Observer {
            subRemoveGame(it)
        })

        PlayGameConnection.selectActive.observe(this, Observer { invalidateOptionsMenu() })

        CmGameSdk.setGameAccountCallback(this)

        CmGameSdk.setGamePlayTimeCallback(this)

        active = true
    }

    private fun subRemoveGame(id: String) = removeIds.remove(id)


    private fun addRemoveGame(id: String) = removeIds.add(id)


    fun removeGame(view: View) {

        launch {
            val restGames = withContext(Dispatchers.IO) { restApi.deleteMyPlayedGame(removeIds).data }

            myGameViewModel.gameData.value = mapMyPlayedGme(restGames)

        }
    }


    override fun onCreateOptionsMenu(menu: Menu?): Boolean {
        if (PlayGameConnection.selectActive.value == false)
            menuInflater.inflate(R.menu.menu_delete, menu)
        else menuInflater.inflate(R.menu.menu_complete, menu)
        return super.onCreateOptionsMenu(menu)
    }


    override fun onOptionsItemSelected(item: MenuItem?): Boolean {
        when (item?.itemId) {
            R.id.delete ->  PlayGameConnection.selectActive.value = true
            R.id.complete -> {
                PlayGameConnection.selectActive.value = false
                PlayGameConnection.cancelGame.value = removeIds
                removeIds.clear()
            }
        }
        return super.onOptionsItemSelected(item)
    }


    fun playMiniGame(gameId: String) {

        if (!isTokenValid()) {
            launchDelayError(errHandler = ::onError) {

                val token2 = restApi.getMiniGameTempToken2().data
                currToken = token2
                CmGameSdk.startH5Game(gameId)
            }
            return
        }

        if (CmGameSdk.hasGame(gameId).not())
            return Toaster.message("该游戏暂时无法运行，请试玩其他游戏($gameId)")

        this.gameId = gameId
        val tinyGameAccount = TokenManager.miniGameAccount()
        if (TokenManager.hasMiniGameAccount().not()) //还没有提交过后台服务器游戏账户信息，请求后台服务器游戏账户信息
            launch {
                try {
                    val res = retryIO { restApi.getMiniGameAccount() }
                    val playToken = res.data.miniGameToken ?: ""
                    currToken = playToken
                    if (playToken.isEmpty())
                        createAccountAndPlayGame()
                    else
                        restoreAccountAndPlayGame(currToken)
                } catch (e: Exception) {
                    onError(e)
                }

            }
        else {
            //直接使用本地缓存的游戏账户
            restoreAccountAndPlayGame(tinyGameAccount)
            userPresenter.postTinyGameLoggedAccountInfo(tinyGameAccount, ::onError)
        }


    }


    fun isTokenValid(): Boolean {
        return TextUtils.isEmpty(currToken).not()
    }

    /**
     * 使用之前缓存的游戏账号继续 玩游戏
     */
    fun restoreAccountAndPlayGame(accountToken: String) {
        if (playing) return
        CmGameSdk.restoreCmGameAccount(accountToken)
        playing = true
        gameStartTime = System.currentTimeMillis()
        CmGameSdk.startH5Game(gameId)


    }

    /**
     * 创建游戏账户后 玩游戏
     */
    private fun createAccountAndPlayGame() {
        if (playing) return
        CmGameSdk.restoreCmGameAccount(null)
        CmGameSdk.clearCmGameAccount()
        playing = true
        gameStartTime = System.currentTimeMillis()
        CmGameSdk.startH5Game(gameId)
    }


    override fun onGameAccount(accountToken: String) {

        TokenManager.saveMiniGameAccount(accountToken)

        launch {
            try {
                restApi.postTinyGameAccountInfo(TinyGameAccountInfo(accountToken))
            } catch (e: Exception) {
                onError(e)
            }
        }

    }

    override fun gamePlayTimeCallback(gameId: String, gamePlayedTimeSeconds: Int) {
        if (active.not())
            return
        playing = false


        val req = GamePlayTimeReport(gameId, gamePlayedTimeSeconds, MD5.getMD5(gameId + gamePlayedTimeSeconds + currToken).toLowerCase())

        launch {
            val gamePlayTime = restApi.postGamePlayTime2(req)
            if (gamePlayTime.isOk()){
                onPlayTimeHandleIn(gamePlayTime.data.diamondRewardNum, gamePlayTime.data.beanRewardNum)
                val res = restApi.getMiniGameTempToken2()
                currToken = res.data
            }else{
                onError(gamePlayTime.error())
            }

        }
    }


    fun onPlayTimeHandleIn(msg: String?, beanReward: String?) {
        currToken = ""
        val view = layoutInflater.inflate(R.layout.play_time_dialog, null)


        val create = AlertDialog.Builder(this)
                .setView(view)
                .create()

        view.tv_reward_diamond.visibility = if (TextUtils.isEmpty(msg)) View.GONE else View.VISIBLE
        view.tv_reward_diamond.text = "+$msg"

        view.tv_reward_bean.visibility = if (TextUtils.isEmpty(beanReward)) View.GONE else View.VISIBLE
        view.tv_reward_bean.text = "+$beanReward"

        view.dialog_button.setOnClickListener {
            apply {
                create.dismiss()
            }
        }
        create.window?.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
        create.show()
    }


    override fun onSupportNavigateUp(): Boolean {
        if (PlayGameConnection.selectActive.value == true) {

            PlayGameConnection.selectActive.value = false
            return false
        }
        onBackPressed()
        return super.onSupportNavigateUp()
    }


    override fun onBackPressed() {
        if (PlayGameConnection.selectActive.value == true) {

            PlayGameConnection.selectActive.value = false
            PlayGameConnection.cancelGame.value = removeIds
            removeIds.clear()
            return
        }
        super.onBackPressed()
    }

    override fun onDestroy() {
        super.onDestroy()
        active = false
        PlayGameConnection.reset()
    }

}
